package org.jeecg.modules.wangyue.payment.alipay.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayFundTransUniTransferModel;
import com.alipay.api.domain.Participant;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.wangyue.constant.RoleConstant;
import org.jeecg.modules.wangyue.payment.alipay.config.AlipayConfig;
import org.jeecg.modules.wangyue.payment.alipay.request.AlipayBackRequest;
import org.jeecg.modules.wangyue.payment.alipay.request.AlipayCloseRequest;
import org.jeecg.modules.wangyue.payment.alipay.request.AlipayRequest;
import org.jeecg.modules.wangyue.payment.alipay.request.AlipayTransferRequest;
import org.jeecg.modules.wangyue.payment.alipay.service.IAlipayService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * @author dhw
 */
@Service
@Slf4j
public class IAlipayServiceImpl implements IAlipayService {

    @Resource
    private AlipayConfig alipayConfig;

    private final AlipayClient alipayClient = new AlipayConfig().alipayClient();

    /**
     * 余额查询
     */
    @Override
    public AlipayFundAccountQueryResponse queryResponse(String sellerId) {
        try {
            AlipayFundAccountQueryRequest alipayFundAccountQueryRequest = new AlipayFundAccountQueryRequest();
            JSONObject bizContent = new JSONObject();
            bizContent.put("alipay_user_id", sellerId);
            bizContent.put("account_type", "ACCTRANS_ACCOUNT");
            alipayFundAccountQueryRequest.setBizContent(bizContent.toString());
            AlipayFundAccountQueryResponse alipayFundAccountQueryResponse = alipayClient.certificateExecute(alipayFundAccountQueryRequest);
            log.info(alipayFundAccountQueryResponse.getBody()); //就是orderString 可以直接给客户端请求，无需再做处理。
            return alipayFundAccountQueryResponse;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 支付宝提现
     */
    @Override
    public AlipayFundTransUniTransferResponse fundTransUniTransfer(AlipayTransferRequest alipayTransferRequest) {
        try {
            AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
            AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();
            Participant payeeInfo = new Participant();
            model.setOutBizNo(alipayTransferRequest.getOutBizNo());
            model.setTransAmount(alipayTransferRequest.getTransAmount());
            model.setProductCode("TRANS_ACCOUNT_NO_PWD");
            model.setBizScene("DIRECT_TRANSFER");
            model.setOrderTitle(alipayTransferRequest.getOrderTitle());
            payeeInfo.setIdentityType("ALIPAY_LOGON_ID");
            payeeInfo.setIdentity(alipayTransferRequest.getIdentity());
            payeeInfo.setName(alipayTransferRequest.getName());
            model.setPayeeInfo(payeeInfo);
            request.setBizModel(model);
            return alipayClient.certificateExecute(request);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 支付宝app支付
     */
    @Override
    public AlipayTradeAppPayResponse appAliPay(AlipayRequest alipayRequest) {
        try {
            //验证秘钥证书
            AlipayClient alipayClient = new AlipayConfig().alipayClient();
            //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
            AlipayTradeAppPayRequest alipayTradeAppPayRequest = new AlipayTradeAppPayRequest();
            //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
            JSONObject bizContent = new JSONObject();
            bizContent.put("out_trade_no", alipayRequest.getOutTradeNo());
            bizContent.put("total_amount", alipayRequest.getTotalAmount());
            bizContent.put("subject", alipayRequest.getSubject());
            //bizContent.put("time_expire", "2022-08-01 22:00:00");
            alipayTradeAppPayRequest.setBizContent(bizContent.toString());
            alipayTradeAppPayRequest.setNotifyUrl(alipayConfig.getNotifyUrl());
            // 提交数据至支付宝时请使用
            return alipayClient.sdkExecute(alipayTradeAppPayRequest);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    //查询支付宝查询接口，查询交易
    @Override
    public AlipayTradeQueryResponse query(String tradeNo) {
        try {
            AlipayTradeQueryRequest alipayTradeQueryRequest = new AlipayTradeQueryRequest();
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("out_trade_no", tradeNo);
            alipayTradeQueryRequest.setBizContent(jsonObject.toString());
            AlipayTradeQueryResponse alipayTradeQueryResponse = alipayClient.certificateExecute(alipayTradeQueryRequest);
            log.info(alipayTradeQueryResponse.getBody());
            log.info(alipayTradeQueryResponse.getTradeStatus());
            return alipayTradeQueryResponse;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void callBack(AlipayBackRequest alipayBackRequest) {
        AlipayTradeQueryResponse alipayTradeQueryResponse = query(alipayBackRequest.getTradeno());
        String tradeStatus = alipayTradeQueryResponse.getTradeStatus();
    }


    @Override
    public AlipayTradeRefundResponse tradeClose(AlipayCloseRequest tradeCloseRequest) {
        try {
            //请求对象,调用支付宝 不同接口，需使用不同对象
            AlipayTradeRefundRequest alipayTradeCloseRequest = new AlipayTradeRefundRequest();
            //请求参数集合对象,除了公共参数之外,所有参数都可通过此对象传递
            JSONObject bizContent = new JSONObject();
            //退款的订单号,传入生成支付订单时的订单号即可
            bizContent.put("out_trade_no", tradeCloseRequest.getOutTradeNo());
            //退款金额
            bizContent.put("refund_amount", tradeCloseRequest.getRefundAmount());
            //退款的原因
            bizContent.put("refund_reason", tradeCloseRequest.getRefundReason());
            alipayTradeCloseRequest.setBizContent(bizContent.toString());
            //退款的执行流程与支付不太一样,支付时成功之后，需要通知回调接口,而退款则不需要,只需判断响应参数 refundResponse.getFundChange().equals("Y") 判断是否发生了资金变化, equals("Y")表示资金发生了变化，退款成功
            return alipayClient.certificateExecute(alipayTradeCloseRequest);
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
    }
}
